package com.aust.dynamicProxy.test2;

import java.lang.reflect.Proxy;

/**
 * 动态代理是 Java 利用反射机制在运行时创建代理类和对象的一种设计模式。
 * 它允许你将对接口方法的调用，统一拦截，然后在调用前后插入自己的逻辑。
 * Java 动态代理（**Dynamic Proxy**）是 Java 反射机制和面向接口编程思想的一种重要应用，它允许我们在运行时动态地创建代理对象，并对目标对象的方法调用进行增强，比如日志记录、权限校验、事务控制等。
 * <p>
 * Proxy：创建代理对象
 * InvocationHandler：定义如何处理方法调用
 */
public class Test {
    public static void main(String[] args) {
        /**
         * 真实对象
         */
        UserService userService = new UserServiceImpl();

        /**
         * 创建代理对象
         * Proxy 是 Java 提供的动态代理类：在运行时创建实现指定接口的一组代理类的实例
         * 类型	                说明	                                        示例
         * ClassLoader	        类加载器，用于加载代理类	                    通常传：原始对象.getClass().getClassLoader()
         * Class<?>[]	        被代理对象实现的接口数组，代理类将实现这些接口	    通常传：原始对象.getClass().getInterfaces()
         * InvocationHandler	方法调用的处理器，每次调用代理方法，都会转发给它	    自己写一个类实现 InvocationHandler
         */
        UserService proxy = (UserService) Proxy.newProxyInstance(
                /**
                 * Java 中的类加载器负责把类加载进内存，动态代理生成的新类必须通过类加载器加载。
                 * 而我们传入目标对象的类加载器，是为了保证生成的代理类能正确地“实现目标接口”、访问目标方法，并避免类加载冲突。
                 * 我们就是通过使用目标对象的类加载器，加载一个实现同样接口的代理类，然后让它“代替”原始对象对外提供服务，实现增强逻辑 —— 所以“代理类对象覆盖原始对象”这个理解是对的，但原始对象通常还在内部被保存着，用于反射调用。
                 */
                userService.getClass().getClassLoader(),
                /**
                 * Class<?>[] interfaces 参数的作用就是：告诉 JVM 你要创建的代理类必须实现哪些接口，从而具备哪些方法。
                 * 1.为了让别人在调用时，把代理对象当作原对象使用，它必须实现相同的接口。
                 * 2.代理类是一个“临时生成的类”，需要指定“它要实现哪些接口”
                 */
                userService.getClass().getInterfaces(),
                /**
                 * InvocationHandler 是一个“方法调用的处理器”，
                 * 它的目的是：当代理对象的方法被调用时，由它统一接管，实现增强逻辑（扩展、拦截、代理等）。
                 * ✔️ InvocationHandler 的作用是 统一定义代理对象调用方法时的处理逻辑，
                 * ✔️ 你交给 Proxy 的，是一个“类加载器 + 接口 + InvocationHandler”，
                 * ✔️ Proxy 会创建出一个实现了这些接口的代理类对象，你就可以拿来用。
                 */
                new LogHandler(userService)
        );

        /**
         * proxy：代理对象
         */
        proxy.login("唐若洁");
        proxy.logout();
    }
}
